# apps/user/models.py
import uuid
from datetime import timedelta

from django.contrib.auth.models import User
from django.db import models
from django.utils import timezone


class Family(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=100, help_text="The name of the family.")
    manager = models.ForeignKey(
        'UserProfile',
        on_delete=models.PROTECT,
        related_name="managed_families",
        verbose_name="家庭管理员"
    )
    description = models.TextField(blank=True, help_text="The description of the family.")

    class Meta:
        verbose_name = "家庭"
        verbose_name_plural = "家庭"

    def __str__(self):
        return f"{self.name} (管理员：{self.manager})"


class FamilyMember(models.Model):
    ROLE_CHOICES = [
        ('admin', '管理员'),
        ('member', '成员')
    ]

    user = models.OneToOneField(User, on_delete=models.CASCADE)
    family = models.ForeignKey(Family, on_delete=models.CASCADE, related_name="members")
    role = models.CharField(max_length=10, choices=ROLE_CHOICES)
    joined_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = "家庭成员"
        verbose_name_plural = "家庭成员"


class InvitationCode(models.Model):
    code = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
    family = models.ForeignKey(Family, on_delete=models.CASCADE)
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    expires_at = models.DateTimeField()
    used = models.BooleanField(default=False)

    def save(self, *args, **kwargs):
        if not self.expires_at:
            self.expires_at = timezone.now() + timedelta(hours=24)
        super().save(*args, **kwargs)

    class Meta:
        verbose_name="邀请码"
        verbose_name_plural="邀请码"


class UserProfile(models.Model):
    # 与内置User模型的一对一关联
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        primary_key=True,
        related_name='userprofile'
    )
    family = models.ForeignKey(
        Family,
        on_delete=models.SET_NULL,
        null=True,
        blank=True
    )
    nickname = models.CharField(
        max_length=50,
        blank=True,
        default=''
    )
    avatar_url = models.URLField(
        max_length=200,
        blank=True,
        default=''
    )
    timezone = models.CharField(
        max_length=40,
        default='UTC'
    )
    onboard_completed = models.BooleanField(
        default=False
    )

    class Meta:
        db_table = 'user_profile'
        verbose_name = '用户资料'
        verbose_name_plural = '用户资料'

    def __str__(self):
        return f"{self.nickname} ({self.user.username})"


class UserPreference(models.Model):
    user = models.ForeignKey(
        UserProfile,
        on_delete=models.CASCADE,
        related_name='preferences'
    )
    key = models.CharField(max_length=40)
    value = models.JSONField()

    class Meta:
        db_table = 'user_preference'
        verbose_name = '用户偏好'
        verbose_name_plural = '用户偏好'
        unique_together = [['user', 'key']]

    def __str__(self):
        return f"{self.user}: {self.key}"


class SessionLog(models.Model):
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='session_logs',
        verbose_name="关联用户"
    )
    ip = models.GenericIPAddressField(verbose_name="IP地址", blank=True, null=True)
    user_agent = models.CharField(max_length=150, verbose_name="用户代理", blank=True, null=True)
    login_at = models.DateTimeField(default=timezone.now)
    logout_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'session_log'
        verbose_name = '会话日志'
        verbose_name_plural = '会话日志'
        indexes = [
            models.Index(fields=['login_at'], name='login_time_idx'),
            models.Index(fields=['logout_at'], name='logout_time_idx')
        ]

    def duration(self):
        if self.logout_at:
            return self.logout_at - self.login_at
        return None

    def __str__(self):
        return f"{self.user} @ {self.login_at}"